#    This file is part of Teacher's P.E.T.
#
#    Teacher's P.E.T. is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Teacher's P.E.T. is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Teacher's P.E.T..  If not, see <http://www.gnu.org/licenses/>.

import sys
import os
import django
from django.conf import global_settings
DJANGO_ROOT = os.path.dirname(os.path.realpath(django.__file__))
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

sys.path.append(os.path.join(SITE_ROOT,'pet_helper_apps.zip','filetransfers'))
sys.path.append(os.path.join(SITE_ROOT,'pet_helper_apps.zip'))

DEBUG = False
TEMPLATE_DEBUG = DEBUG

ADMINS = (
	(),
)

MANAGERS = ADMINS

DATABASES = {
	'default': {
		'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
		'NAME': os.path.join(SITE_ROOT,'classdb.db'),                      # Or path to database file if using sqlite3.
		'USER': '',                      # Not used with sqlite3.
		'PASSWORD': '',                  # Not used with sqlite3.
		'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
		'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
	}
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Denver'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale
USE_L10N = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = os.path.join(SITE_ROOT,'media')
STATIC_ROOT = os.path.join(SITE_ROOT,'static')

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = '/media/'
STATIC_URL = '/static/'

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
#ADMIN_STATIC_PREFIX = '/static-admin/'

# Make this unique, and don't share it with anybody.
SECRET_KEY = '#zc(p4*bwl0@ltgpo)sc(6nr9vct(%ui2=60gni3j8&m&djr9)'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
	'django.template.loaders.filesystem.Loader',
	'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
	'django.middleware.gzip.GZipMiddleware',
	'django.middleware.common.CommonMiddleware',
	'django.contrib.sessions.middleware.SessionMiddleware',
	'django.middleware.csrf.CsrfViewMiddleware',
	'django.contrib.auth.middleware.AuthenticationMiddleware',
	'django.middleware.http.ConditionalGetMiddleware',
	'django.contrib.messages.middleware.MessageMiddleware',
	'crashlog.CrashLogMiddleware',
)

ROOT_URLCONF = 'urls'

TEMPLATE_DIRS = (
	# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
	# Always use forward slashes, even on Windows.
	# Don't forget to use absolute paths, not relative paths.
	os.path.join(SITE_ROOT, 'templates'),
)

INSTALLED_APPS = (
	'south',
	'djangooptions',
	'filetransfers',
	'compressor',
	'tinymce',
	'apps.additions',
	'apps.participants',
	'django.contrib.auth',
	'django.contrib.contenttypes',
	'django.contrib.sessions',
	'django.contrib.messages',
	'django.contrib.staticfiles',
	'django.contrib.humanize',
	# Uncomment the next line to enable the admin:
	'django.contrib.admin',
	# Uncomment the next line to enable admin documentation:
	#'django.contrib.admindocs',
	'apps.feeds',
	'apps.course',
	'apps.contact',
	'apps.files',
	'apps.forum',
	'apps.news',
	'apps.gradebook',
	'apps.activities',
	'apps.help',
	'apps.management',
	'crashlog',
)

TEST_RUNNER = 'testing.simple.AdvancedTestSuiteRunner'
TESTING_EXCLUDE_APPS = ['south','djangooptions','compressor','filetransfers','tinymce','django','crashlog' ]

from django.template import add_to_builtins, builtins, import_library
if not import_library('apps.course.templatetags.course_url') in builtins:
	add_to_builtins('apps.course.templatetags.course_url')
if not import_library('tags.templatetags.render') in builtins:
	add_to_builtins('tags.templatetags.render')
if not import_library('tags.templatetags.spacify') in builtins:
	add_to_builtins('tags.templatetags.spacify')
if not import_library('tags.templatetags.sanitize') in builtins:
	add_to_builtins('tags.templatetags.sanitize')
if not import_library('tags.templatetags.getitem') in builtins:
	add_to_builtins('tags.templatetags.getitem')
if not import_library('tags.templatetags.concat') in builtins:
	add_to_builtins('tags.templatetags.concat')
if not import_library('tags.templatetags.strip_html') in builtins:
	add_to_builtins('tags.templatetags.strip_html')
if not import_library('tags.templatetags.natural_sort') in builtins:
	add_to_builtins('tags.templatetags.natural_sort')
if not import_library('django.contrib.humanize.templatetags.humanize') in builtins:
	add_to_builtins('django.contrib.humanize.templatetags.humanize')

def updated_media_context_processor(request):
	"""
	Adds media-related context variables to the context.
	"""
	from django.conf import settings
	if not settings.ADMIN_MEDIA_PREFIX.startswith(request.META['SCRIPT_NAME']):
		settings.ADMIN_MEDIA_PREFIX = request.META['SCRIPT_NAME'] + settings.ADMIN_MEDIA_PREFIX
	return {'MEDIA_URL': request.META['SCRIPT_NAME'] + settings.MEDIA_URL,
		'STATIC_URL': request.META['SCRIPT_NAME'] + settings.STATIC_URL}
	
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
					'settings.updated_media_context_processor',
					'apps.course.context_processors.course',
					'apps.participants.context_processors.participants',
					'django.core.context_processors.request',
					#'django.core.context_processors.auth',
					'django.contrib.messages.context_processors.messages',
					'apps.management.context_processors.management',
					'apps.activities.context_processors.activities',
					)
STATICFILES_DIRS = global_settings.STATICFILES_DIRS + (SITE_ROOT + '/site_static',)
MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'

#Save the session everytime the user visits the site
SESSION_SAVE_EVERY_REQUEST = True

#Turn on Tinymce compression
TINYMCE_COMPRESSOR = True

#Turn on compression all the time
COMPRESS_ENABLED = True
#Staticfile finder for compression
STATICFILES_FINDERS = global_settings.STATICFILES_FINDERS + ('compressor.finders.CompressorFinder',)
# Storage engine to be used during compression
COMPRESS_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"
# The URL that linked media will be read from and compressed
# media will be written to.
COMPRESS_URL = STATIC_URL
# The absolute file path that linked media will be read from
# and compressed media will be written to.
COMPRESS_ROOT = STATIC_ROOT


#SESSION_COOKIE_SECURE = True

#Set new log levels with ability to get caller function info
import logging
import inspect

def caller_name(skip=3):
	"""Get a name of a caller in the format module.class.method
	
	   `skip` specifies how many levels of stack to skip while getting caller
	   name. skip=1 means "who calls me", skip=2 "who calls my caller" etc.
	   
	   An empty string is returned if skipped levels exceed stack height
	"""
	stack = inspect.stack()
	start = 0 + skip
	if len(stack) < start + 1:
	  return ''
	parentframe = stack[start][0]    
	
	name = []
	module = inspect.getmodule(parentframe)
	# `modname` can be None when frame is executed directly in console
	# TODO(techtonik): consider using __main__
	if module:
		name.append(module.__name__)
	# detect classname
	if 'self' in parentframe.f_locals:
		# I don't know any way to detect call from the object method
		# XXX: there seems to be no way to detect static method call - it will
		#      be just a function call
		name.append(parentframe.f_locals['self'].__class__.__name__)
	codename = parentframe.f_code.co_name
	lineno = parentframe.f_lineno
	if codename != '<module>':  # top level usually
		name.append( codename ) # function or a method
	del parentframe
	return ".".join(name) + '():%s' % lineno

LEVEL_HTTP404 = 12
LEVEL_FORCED_REDIRECT = 11
LEVEL_FXN_ENTRY = 8
LEVEL_FXN_EXIT = 7
LEVEL_DISPLAY = 3
LEVEL_FIND = 2
LEVEL_FORM_UNCHANGED = 1

logging.addLevelName(LEVEL_HTTP404, "HTTP404")
logging.addLevelName(LEVEL_FORCED_REDIRECT, "FORCED_REDIRECT")
logging.addLevelName(LEVEL_FXN_ENTRY, "FXN_ENTRY")
logging.addLevelName(LEVEL_FXN_EXIT, "FXN_EXIT")
logging.addLevelName(LEVEL_DISPLAY,'DISPLAY')
logging.addLevelName(LEVEL_FIND, "FIND")
logging.addLevelName(LEVEL_FORM_UNCHANGED, "FORM_UNCHANGED")

pet_logging_caller_str = 'From %s()\n\t'
def log_http404(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',False): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_HTTP404): self._log(LEVEL_HTTP404, message, args, **kwargs)
def log_forced_redirect(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',False): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_FORCED_REDIRECT): self._log(LEVEL_FORCED_REDIRECT, message, args, **kwargs)
def log_fxn_entry(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',False): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_FXN_ENTRY): self._log(LEVEL_FXN_ENTRY, message, args, **kwargs)
def log_fxn_exit(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',False): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_FXN_EXIT): self._log(LEVEL_FXN_EXIT, message, args, **kwargs)
def log_display(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',True): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_DISPLAY): self._log(LEVEL_DISPLAY, message, args, **kwargs)
def log_find_fxn(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',True): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_FIND): self._log(LEVEL_FIND, message, args,**kwargs);
def log_form_unchanged(self, message, *args, **kwargs):
	if kwargs.pop('display_caller',False): kwargs['extra'] = {'caller':caller_name()}
	if self.isEnabledFor(LEVEL_FORM_UNCHANGED): self._log(LEVEL_FORM_UNCHANGED, message, args, **kwargs);

logging.Logger.http404 = log_http404
logging.Logger.forced_redirect = log_forced_redirect
logging.Logger.fxn_entry = log_fxn_entry
logging.Logger.fxn_exit = log_fxn_exit
logging.Logger.display = log_display
logging.Logger.find_fxn = log_find_fxn
logging.Logger.form_unchanged = log_form_unchanged

class PetLoggingFormatter(logging.Formatter):
	format_dict = {
		'multiline': '[%(asctime)s] [%(levelname)-7s] %(name)s.%(funcName)s():%(lineno)d:\n\t%(message)s\n',
		'multiline_caller':'[%(asctime)s] [%(levelname)-7s] %(caller)s -> %(name)s.%(funcName)s():%(lineno)d:\n\t%(message)s\n',
		'simple': '[%(asctime)s] [%(levelname)-7s] %(name)s.%(funcName)s():%(lineno)d: %(message)s',
		'simple_caller': '[%(asctime)s] [%(levelname)-7s] %(caller)s -> %(name)s.%(funcName)s():%(lineno)d: %(message)s',
	}
	level_dict = {
		LEVEL_HTTP404: 'multiline',
		LEVEL_FORCED_REDIRECT: 'multiline',
		LEVEL_FXN_ENTRY: 'simple',
		LEVEL_FXN_EXIT: 'simple',
		LEVEL_DISPLAY: 'multiline',
		LEVEL_FIND: 'simple',
		LEVEL_FORM_UNCHANGED: 'simple',
		logging.DEBUG: 'multiline',
		logging.INFO: 'simple',
		logging.WARNING: 'multiline',
		logging.ERROR: 'multiline',
		logging.CRITICAL: 'multiline',
	}
	def format(self, record):
		format_orig = self._fmt
		if record.levelno in self.level_dict:
			if 'caller' in record.__dict__:
				self._fmt = self.format_dict[self.level_dict[record.levelno]+'_caller']
			else:
				self._fmt = self.format_dict[self.level_dict[record.levelno]]
		result = logging.Formatter.format(self,record)
		self._fmt = format_orig
		return result
	
LOGGING = {
	'version': 1,
	#'disable_existing_loggers': True,
	'formatters': {
		'pet': {
			'()': 'pet.settings.PetLoggingFormatter',
			'format': 'blah blah blah'
		},
	},
	'handlers': {
		'null': {
			'level':'DEBUG',
			'class':'django.utils.log.NullHandler',
			'formatter': 'pet'
		},
		'console':{
			'level':'DISPLAY',
			'class':'logging.StreamHandler',
			'formatter': 'pet'
		},
		'mail_admins': {
			'level': 'ERROR',
			'class': 'django.utils.log.AdminEmailHandler',
			'include_html': True,
			'formatter': 'pet'
		},
		'log_file': {
			'level':'FORM_UNCHANGED',
			'class':'logging.handlers.RotatingFileHandler',
			'filename':'pet.log',
			'maxBytes':1024*1024,
			'backupCount':5,
			'delay':True,
			'formatter': 'pet',
		}
	},
	'loggers': {
		'django': {
			'handlers':['console'],
			'propagate': True,
			'level':'ERROR',
		},
		'pet.apps': {
			'handlers': ['console','log_file'],
			'level': 'FORM_UNCHANGED',
		}
	}
}
